Skip to content

Webhook - #490

Draft
thokra-nav wants to merge 8 commits into
mainfrom
webhook
Draft

Webhook#490
thokra-nav wants to merge 8 commits into
mainfrom
webhook

Conversation

@thokra-nav

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces an activity-log–driven webhook system (DB outbox + dispatcher) and exposes management + event-type discovery through the GraphQL API. This extends the existing activitylog infrastructure by formalizing “activity types” with webhook-facing metadata (description/group/scope) and wiring a dispatcher into the API runtime.

Changes:

  • Added webhook subscription + delivery pipeline (Postgres outbox tables, dispatcher, retries/backoff, pruning, metrics, signing, CloudEvents payloads).
  • Exposed webhook CRUD + listing + event-type catalogue via GraphQL schema and resolvers.
  • Refactored activity log registration from RegisterFilter to RegisterActivityType and added webhook metadata options (description/group/global-only/ignore).

Reviewed changes

Copilot reviewed 50 out of 54 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
internal/workload/secret/activitylog.go Migrates secret activity types to RegisterActivityType with descriptions.
internal/workload/job/activitylog.go Migrates job activity types to RegisterActivityType with descriptions.
internal/workload/config/activitylog.go Migrates config activity types to RegisterActivityType with descriptions.
internal/workload/application/activitylog.go Migrates application activity types to RegisterActivityType with descriptions.
internal/vulnerability/activitylog.go Migrates vulnerability activity type to RegisterActivityType with description.
internal/unleash/activitylog.go Migrates Unleash activity types to RegisterActivityType (ignores webhooks).
internal/tunnel/activitylog.go Migrates tunnel activity types to RegisterActivityType (ignores webhooks).
internal/team/activitylog.go Migrates team activity types to RegisterActivityType, adds GlobalOnly where relevant.
internal/serviceaccount/activitylog.go Migrates service account activity types to RegisterActivityType with descriptions.
internal/reconciler/activitylog.go Migrates reconciler activity types to RegisterActivityType (GlobalOnly).
internal/persistence/valkey/activitylog.go Migrates Valkey activity types to RegisterActivityType with descriptions.
internal/persistence/postgres/activitylog.go Migrates Postgres activity types to RegisterActivityType with descriptions.
internal/persistence/opensearch/activitylog.go Migrates OpenSearch activity types to RegisterActivityType with descriptions.
internal/kubernetes/event/pubsublog/activitylog.go Migrates cluster audit activity type to RegisterActivityType (GlobalOnly).
internal/integration/manager.go Updates Graph runner construction to pass webhookDispatcher (nil in tests).
internal/graph/webhooks.resolvers.go Adds GraphQL resolvers for webhook CRUD, listing, deliveries, and event type catalogue.
internal/graph/schema/webhooks.graphqls Adds GraphQL schema for webhook subscriptions, deliveries, inputs/payloads, and queries/mutations.
internal/graph/gengql/teams.generated.go Generated: adds Team.webhooks field plumbing.
internal/graph/gengql/schema.generated.go Generated: adds webhook queries/mutations and node unions.
internal/graph/gengql/prelude.generated.go Generated: adds marshal/unmarshal support for ActivityLogActivityType.
internal/graph/gengql/complexity.go Generated: adds complexity functions for webhook connections.
internal/github/repository/activitylog.go Migrates repository activity types to RegisterActivityType with descriptions.
internal/deployment/deploymentactivity/activitylog.go Migrates deploy-key activity type to RegisterActivityType.
internal/database/migrations/0072_webhooks.sql Adds webhook tables (subscriptions/outbox/queue/audit), trigger, and authorizations.
internal/cmd/api/http.go Wires webhook loader context + dispatcher into request context.
internal/cmd/api/api.go Starts webhook dispatcher + cleaner during API startup and passes dispatcher to Graph config.
internal/auth/authz/queries.go Adds authorization helpers for webhook create/update/delete.
internal/activitylog/webhook/webhooksql/webhook.sql.go Generated (sqlc): webhook SQL query implementations.
internal/activitylog/webhook/webhooksql/querier.go Generated (sqlc): Querier interface for webhook SQL.
internal/activitylog/webhook/webhooksql/models.go Generated (sqlc): webhook SQL models/enums.
internal/activitylog/webhook/webhooksql/db.go Generated (sqlc): DB wrapper for webhook SQL.
internal/activitylog/webhook/signer.go Adds HMAC-SHA256 signing for webhook payloads.
internal/activitylog/webhook/signer_test.go Unit tests for signing helper.
internal/activitylog/webhook/README.md Documents the webhook system architecture and operational characteristics.
internal/activitylog/webhook/queries/webhook.sql Defines sqlc queries for webhook subscriptions, outbox, queue, and audits.
internal/activitylog/webhook/queries.go Implements webhook CRUD/listing, masking, and event-type validation.
internal/activitylog/webhook/queries_test.go Unit tests for secret masking and event-type validation.
internal/activitylog/webhook/node.go Adds Node ident registration for webhook subscription/delivery nodes.
internal/activitylog/webhook/node_test.go Unit tests for webhook ident round-trips and error cases.
internal/activitylog/webhook/model.go Defines webhook domain models and matching logic.
internal/activitylog/webhook/model_test.go Unit tests for subscription/event matching behavior.
internal/activitylog/webhook/metrics.go Adds OpenTelemetry metrics for dispatcher + queue gauge.
internal/activitylog/webhook/dispatcher.go Implements outbox drain, fan-out, delivery, retry/backoff, and ping logic.
internal/activitylog/webhook/dispatcher_integration_test.go Integration tests covering end-to-end dispatcher behavior with Postgres + HTTP servers.
internal/activitylog/webhook/dataloader.go Adds dataloaders and DB access wiring for GraphQL.
internal/activitylog/webhook/cloudevents.go Builds CloudEvents envelopes and maps activity types to io.nais.* type strings.
internal/activitylog/webhook/cloudevents_test.go Unit tests for CloudEvents envelope + type mapping.
internal/activitylog/webhook/cleaner.go Adds leader-only periodic pruning of webhook tables.
internal/activitylog/filter.go Introduces RegisterActivityType + webhook metadata options + event type catalogue functions.
internal/activitylog/filter_test.go Adds tests for activity type registration behavior and webhook metadata utilities.
.configs/sqlc.yaml Adds sqlc generation target for webhook SQL.
.configs/gqlgen.yaml Adds webhook package to gqlgen autobind list.
Files not reviewed (4)
  • internal/activitylog/webhook/webhooksql/db.go: Generated file
  • internal/activitylog/webhook/webhooksql/models.go: Generated file
  • internal/activitylog/webhook/webhooksql/querier.go: Generated file
  • internal/activitylog/webhook/webhooksql/webhook.sql.go: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +243 to +248
// The CloudEvent id is derived from the delivery row's own id, so it stays stable across retries.
payload, err := BuildCloudEvent(d.source, del.ID.String(), event)
if err != nil {
d.log.WithError(err).Error("building CloudEvent payload")
return
}
Comment on lines +200 to 214
desc, grp := autoGroupAndDescription(activityType)
info := &WebhookEventTypeInfo{
Type: activityType,
CloudEventType: CloudEventType(activityType),
Description: desc,
Group: grp,
TeamScoped: true,
}
knownFilters[activityType] = filter{
action: action,
resourceType: []ActivityLogEntryResourceType{resourceType},

for _, opt := range opts {
opt(info)
}
rebuildReverseFilters()

eventTypeInfos[activityType] = *info
}
Comment on lines +70 to +76
// groupPrefixes maps known multi-word prefixes to their display group names.
var groupPrefixes = map[string]string{
"SERVICE_ACCOUNT": "Service Account",
"GENERIC_KUBERNETES_RESOURCE": "Kubernetes",
"OPENSEARCH": "OpenSearch",
"JOB_RUN": "Job",
}
Comment on lines +103 to +108
activitylog.RegisterActivityType(
"GENERIC_KUBERNETES_RESOURCE_CREATED",
activitylog.ActivityLogEntryActionCreated,
ActivityLogEntryResourceTypeJob,
activitylog.WithDescription("Triggered when a generic Kubernetes resource is created."),
)
Comment on lines +106 to +111
activitylog.RegisterActivityType(
"GENERIC_KUBERNETES_RESOURCE_CREATED",
activitylog.ActivityLogEntryActionCreated,
ActivityLogEntryResourceTypeApplication,
activitylog.WithDescription("Triggered when a generic Kubernetes resource is created."),
)
Comment on lines +22 to +28
CREATE INDEX idx_webhook_subscriptions_team ON webhook_subscriptions (team_slug)
;

CREATE INDEX idx_webhook_subscriptions_global ON webhook_subscriptions (id)
WHERE
team_slug IS NULL
;
@thokra-nav

thokra-nav commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Endringer:
Team kan subscribe på tvers av team
Fjerne secret fra webhook output i graphql
Fjerne Admin only webhook for nå (skru av admin handlinger fra actions)
webhook_deliveries - Bytt data kolonner til bytea
Lagre request og response headere
Trigger time and ID for the activity log entry in the clouevent data body
Erstatte ping med en "Test event" løsning brukeren kan trigge når de ønsker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants